//
//  BTManager.m
//  BMS
//
//  Created by 颜魏 on 2021/4/16.
//

#import "BTManager.h"

#define serviceUUID @"6E400001-B5A3-F393-E0A9-E50E24DCCA9E"
#define writeCharacter @"6E400002-B5A3-F393-E0A9-E50E24DCCA9E"
#define notifyCharacter @"6E400003-B5A3-F393-E0A9-E50E24DCCA9E"

//#define serviceUUID @"FFF0"
//#define writeCharacter @"FFF1"
//#define notifyCharacter @"FFF2"


@interface BTManager()<CBCentralManagerDelegate, CBPeripheralDelegate>

@property (strong, nonatomic) CBCentralManager *manager;        //BLE 管理中心
//@property (strong, nonatomic) CBPeripheral     *peripheral;     //外设-蓝牙硬件
@property (strong, nonatomic) CBCharacteristic *notifyCharacteristic;     //外设-蓝牙硬件

//@property (strong, nonatomic) NSMutableArray    *peripherals;   // 发现的所有 硬件设备
@property (strong, nonatomic) NSMutableArray    *RSSIArray; // 蓝牙信号数组
@property (nonatomic, strong) NSMutableData     *wholeData; //完整数据
@property (nonatomic, assign) NSInteger         dataLength; //数据长度
@property (nonatomic, assign) NSInteger         tempDataLength; //数据长度
@property (nonatomic, strong) NSString          *writeUUID; //
@property (nonatomic, strong) NSString          *kServiceUUID; //


@property (nonatomic, copy) BTManagerDisconnectPeripheralCallBlock disconnectBlock;

//@property (strong, nonatomic) CBPeripheral     *batteryPeripheral;     //外设-蓝牙硬件
@property (nonatomic, strong) NSMutableArray *batteryLevelSource;
@property (strong, nonatomic) NSTimer   *timer;
@property (assign, nonatomic) BOOL isReadCurrentBattery;
@property (assign, nonatomic) NSInteger  readCount;
@property (assign, nonatomic) BOOL isConnectTimeOut;
@property (nonatomic, strong) NSMutableDictionary *diviceNameDict;
@property (nonatomic, assign) BOOL isUpgrading;

@end

@implementation BTManager

static BTManager *shareManager;
+ (instancetype)sharedBTManager {
    if (!shareManager) {
        shareManager = [[super allocWithZone:NULL] init];
    }
    return shareManager;
}

- (instancetype)init {
    self = [super init];
    self.manager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
    self.manager.delegate = self;
    self.isAutoDisconnect = YES;
    self.isInitiativeDis = NO;
    self.dataLength = -1;
    self.readCount = 0;
    self.wholeData=[[NSMutableData alloc] init];
    self.batteryLevelSource = [[NSMutableArray alloc] init];
    self.diviceNameDict = [[NSMutableDictionary alloc] init];
    self.isUpgrading = NO;

    return self;
}

- (void)upgradeUpdate:(NSNotification *)nf {
    self.isUpgrading = [nf.object integerValue] == 1;
}

#pragma mark - public
- (BOOL)isLECapableHardware {
    NSString * state = nil;
    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 10.0) {
        switch ([_manager state]) {
            case CBManagerStateUnsupported://不支持
                state = @"不支持";
                break;
            case CBManagerStateUnauthorized://未授权
                state = @"未授权";
                break;
            case CBManagerStatePoweredOff://蓝牙关闭
            {
                state = @"蓝牙关闭";
                [[NSNotificationCenter defaultCenter] postNotificationName:kBTPoweredOff object:nil];
                break;
            }
            case CBManagerStatePoweredOn://蓝牙打开
                return YES;
            case CBManagerStateUnknown://未知状态
            default:
                return NO;
        }
    }
    NSLog(@"蓝牙状态为: %@", state);
    
    return NO;
}

- (void)startScan {
    if (!self.isScaning) {
        if ([self isLECapableHardware]) {
            if (self.peripherals) {
                // 发现的所有 硬件设备
                [self.peripherals removeAllObjects];
                // 蓝牙信号数组
                [self.RSSIArray removeAllObjects];
            } else {
                // 发现的所有 硬件设备
                self.peripherals = [NSMutableArray array];
                // 蓝牙信号数组
                self.RSSIArray = [NSMutableArray array];
            }
            //是否正在扫描 是=yes，没有=no
            self.isScaning = YES;
            
            NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES],CBCentralManagerScanOptionAllowDuplicatesKey, nil];
            [self.manager scanForPeripheralsWithServices:nil options:options];
//            [self performSelector:@selector(stopScan) withObject:nil afterDelay:20];
            //        }
            // 针对性扫描  serviceUUIDs = [NSArray arrayWithObject:[CBUUID UUIDWithString:@"180D"]]
            // 其中  180D 就是对外公开的 1 级 服务UUID
            //        [_manager scanForPeripheralsWithServices:[NSArray arrayWithObject:[CBUUID UUIDWithString:@"B302D3B1-A81C-90FC-8727-F8B9C1D7CC77"]] options:nil];
            
        } else {
            if (self.scanBlock) {
                self.scanBlock(_peripherals);
                self.scanBlock(nil);
            }
        }
    }
}

- (void)startScanWithInterval:(NSInteger)scanInterval completion:(BTManagerDiscoverPeripheralCallBack)callBack {
    self.scanBlock = callBack;
    [self startScan];
    [self performSelector:@selector(stopScan) withObject:nil afterDelay:scanInterval];
}

- (void)stopScan {
    self.isScaning = NO;
    [self.manager stopScan];
    if (self.scanBlock) {
        self.scanBlock(self.peripherals);
        self.scanBlock(nil);
    }
}

- (void)restartC {
    if (!self.isGettingBattery) {
        return;
    }
    NSLog(@"连接蓝牙 超时---- %@", self.peripheral.name);
    BOOL isHave = NO;
    for (NSInteger i=0; i<self.batteryLevelSource.count; i++) {
        NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithDictionary:self.batteryLevelSource[i]];
        if ([[dict objectForKey:@"name"] isEqualToString:self.peripheral.name]) {
            isHave = YES;
            [self.batteryLevelSource removeObjectAtIndex:i];
            [self.batteryLevelSource addObject:@{@"name": self.peripheral.name, @"batteryLevel": @"-1"}];
            break;
        }
    }
    if (!isHave) {
        [self.batteryLevelSource addObject:@{@"name": self.peripheral.name, @"batteryLevel": @"-1"}];
        [[NSNotificationCenter defaultCenter] postNotificationName:kBTGetBatteryLevel object:self.batteryLevelSource];
        [self.manager cancelPeripheralConnection:self.peripheral];
        self.isReadCurrentBattery = NO;
        self.peripheral = nil;
        [self.timer invalidate];
        self.timer = nil;
        [self didReciveBatteryData:nil];
    }
}

- (void)connectPeripheral:(CBPeripheral *)peripheral {
    self.peripheral = peripheral;
    NSLog(@"连接蓝牙---- %@",peripheral.name);
    self.isConnectTimeOut = YES;
    [self.manager connectPeripheral:peripheral options:[NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:CBConnectPeripheralOptionNotifyOnDisconnectionKey]];
    
    [self performSelector:@selector(restartC) withObject:self afterDelay:10];
}

- (void)connectPeripheral:(CBPeripheral *)peripheral completion:(BTManagerConnectPeripheralCallBack)callBack {
    self.connectBlock = callBack;
    [self connectPeripheral:peripheral];
    [self performSelector:@selector(connectTimeOutAction) withObject:nil afterDelay:5.0];
}

- (void)connectTimeOutAction {
    if (!self.isConnected) {
        if (self.connectBlock) {
            self.connectBlock(NO);
            self.connectBlock = nil;
        }
    }
}

- (void)reConnectPeripheral {
    if (self.peripheral) {
        [self.manager connectPeripheral:self.peripheral options:[NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:CBConnectPeripheralOptionNotifyOnDisconnectionKey]];
    }
}

- (void)reConnectPeripheral:(CBPeripheral *)peripheral {
    [self.manager connectPeripheral:peripheral options:[NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:CBConnectPeripheralOptionNotifyOnDisconnectionKey]];
}

- (void)disconnectPeripheral:(CBPeripheral *)peripheral {
    NSLog(@"disconnectPeripheral");
    if (peripheral) {
        self.isInitiativeDis =YES;
        [self.manager cancelPeripheralConnection:peripheral];
    }
    self.isConnected = NO;
    // 主动链接
//    if (self.peripheral) {
//        self.peripheral.delegate = nil;
//        self.peripheral = nil;
//    }
}

- (void)retartScan {
    if (self.isScaning) {
        [self stopScan];
        if (_isConnected) {
            [self disconnectPeripheral:_peripheral];
        } else {
            [self startScan];
        }
    }else{
        [self startScan];
    }
}

- (void)disconnectRootPeripheral {
    if (self.peripheral) {
        [self.manager cancelPeripheralConnection:self.peripheral];
        self.isConnected = NO;
        self.isAutoDisconnect = NO;
        self.isInitiativeDis = YES; // 主动断开
    }
}

- (void)disconnectRootPeripheral:(BTManagerDisconnectPeripheralCallBlock)callBlock {
    self.disconnectBlock = callBlock;
    [self disconnectRootPeripheral];
}

- (BOOL)writeData:(NSData *)data encoding:(NSStringEncoding)encoding {
    if (self.isConnected && self.writeCharacteristic) {
        [self.peripheral writeValue:data forCharacteristic:self.writeCharacteristic type:CBCharacteristicWriteWithoutResponse];
        return YES;
    }
    return NO;
}

- (void)sendCommandWithCrc:(Byte*)commandData length:(int)length {
    int crc;
    crc = CRC16RTU(commandData, length-2);
    commandData[length-2] = [self getLowByte:crc];
    commandData[length-1] = [self getHighByte:crc];
    if (!self.peripheral) return;
    if (!_writeCharacteristic) return;
    NSData* data = [NSData dataWithBytes:commandData length:length ];
    NSData *first20Byte ,*second20Bytes,*third20Bytes;
    if(data.length>=20) {
        first20Byte=[data subdataWithRange:NSMakeRange(0, 20)];
    }else {
        first20Byte=[data subdataWithRange:NSMakeRange(0, data.length)];
    }
    if(data.length<=20) {
        [self sendCommand:first20Byte];
    }else {
        [self sendCommand:first20Byte];
        if (data.length<40) {
            second20Bytes=[data subdataWithRange:NSMakeRange(20, data.length-20)];
            [self performSelector:@selector(sendCommand:) withObject:second20Bytes afterDelay:0.1];
        }else if (data.length<60) {
            second20Bytes=[data subdataWithRange:NSMakeRange(20, 20)];
            third20Bytes=[data subdataWithRange:NSMakeRange(40, data.length-40)];
            [self performSelector:@selector(sendCommand:) withObject:second20Bytes afterDelay:0.1];
            [self performSelector:@selector(sendCommand:) withObject:third20Bytes afterDelay:0.2];
        }
    }
}

- (void)sendCommand:(NSData*)senddata{
    if (!self.peripheral) return;
    if (!self.writeCharacteristic) return;
    [self.peripheral writeValue:senddata forCharacteristic:self.writeCharacteristic type:CBCharacteristicWriteWithoutResponse];
    [self.peripheral writeValue:senddata forCharacteristic:self.writeCharacteristic type:self.type == 1 ? CBCharacteristicWriteWithResponse : CBCharacteristicWriteWithoutResponse];
}

- (void)sendCommand:(Byte*)commandData length:(int)length {
    if (!self.peripheral) return;
    if (!self.writeCharacteristic) return;
    
    NSData *data = [NSData dataWithBytes:commandData length:length ];
    [self.peripheral writeValue:data forCharacteristic:self.writeCharacteristic type:self.type == 1 ? CBCharacteristicWriteWithResponse : CBCharacteristicWriteWithoutResponse];
}

unsigned int CRC16RTU(unsigned char* pszBuf, unsigned char unLength) {
    unsigned int CRC = 0xFFFF;
        unsigned long CRC_count;
        for(CRC_count = 0; CRC_count < unLength; CRC_count++){
            int i;
            CRC = CRC^*(pszBuf + CRC_count);
            for(i = 0; i < 8; i++){
                if(CRC&1){
                    CRC>>=1;
                    CRC^=0xA001;
                } else{
                    CRC>>=1; }
            }
        }
    return CRC;
}

- (int)getHighByte:(long)value {
    return (int)value/256;
}

- (int)getLowByte:(long)value {
    return (int)(value-(value/256)*256);
}

- (BOOL)isDataCRCOK:(NSData*)data {
    Byte* verifyBytes=(Byte*)data.bytes;
    int crc;
    int crcHigh,crcLow;
    crc=CRC16RTU(verifyBytes, data.length-2);
    crcLow = [self getLowByte:crc];
    crcHigh = [self getHighByte:crc];
    if ((crcLow==verifyBytes[data.length-2]) &&
        (crcHigh==verifyBytes[data.length-1])) {
        return true;
    }
    NSLog(@"CRC ERROR");
    if (self.isUpgrading) {
        [[NSNotificationCenter defaultCenter] postNotificationName:kBTUpgradeFail object:nil];
    }

    return false;
}

#pragma mark - CBCentralManagerDelegate, CBPeripheralDelegate
#pragma mark -  第一步：蓝牙断开走这个方法。这是系统的回调方法，当手机蓝牙断开时会在这个方法，监测设备蓝牙状态发生改变
- (void)centralManagerDidUpdateState:(CBCentralManager *)central {
    if ([self isLECapableHardware]) {
          [self startScan];
     } else {
        NSLog(@"手机蓝牙已关闭");
    }
}

/*
 *发现蓝牙设备
 */
#pragma mark - 第二步：发现蓝牙设备
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)aPeripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI {
    if (aPeripheral.name.length == 0) {
        return;
    }
    //判断是否在数组中 如果没在数组中
    NSString *localName = [advertisementData objectForKey:@"kCBAdvDataLocalName"] ?: @"";
    [self.diviceNameDict setValue:localName forKey:aPeripheral.name];
    [[NSNotificationCenter defaultCenter] postNotificationName:kBTSearchDevicesName object:self.diviceNameDict];
//    if (![self.peripherals containsObject:aPeripheral]) {
    if (![self.peripherals containsObject:aPeripheral] && [aPeripheral.name containsString:@"BT"]) {
        NSLog(@"已经搜索到设备 ：%@",aPeripheral.name);
        [self.peripherals addObject:aPeripheral];
        [[NSNotificationCenter defaultCenter] postNotificationName:kBTSearchDevices object:self.peripherals];
    }
    [self.RSSIArray addObject:RSSI];
}

/*
 Invoked when the central manager retrieves the list of known peripherals.
 Automatically connect to first known peripheral
 */
#pragma mark 当中央管理器调用检索列表中已知的外围设备。自动连接到第一个已知的外围
- (void)centralManager:(CBCentralManager *)central didRetrievePeripherals:(NSArray *)peripherals {
    /* If there are any known devices, automatically connect to it.*/
    if(self.peripherals.count >= 1) {
//        self.peripheral = peripherals.firstObject;
//        NSLog(@"当中央管理器调用检索列表中已知的外围设备。自动连接到第一个已知的外围........此设备名为==%@",_peripheral.name);
//        [self.manager connectPeripheral:self.peripheral options:[NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:CBConnectPeripheralOptionNotifyOnDisconnectionKey]];
    }
}

/*
 *Invoked whenever a connection is succesfully created with the peripheral.
 *Discover available services on the peripheral
 *已连接到设备
 */
#pragma mark - 第三步：已连接到设备-----每当调用是成功创建连接外围。外围发现可用的服务 aPeripheral.identifier.UUIDString 是唯一的UUID，identifier是他唯一的UUID值，拿到他保存起来
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)aPeripheral {
    NSLog(@"蓝牙连接成功-----%@", aPeripheral.name);
    [aPeripheral setDelegate:self];
    [aPeripheral discoverServices:nil];
    self.isConnectTimeOut = NO;
    
    self.isConnected = YES;
    self.isInitiativeDis = NO;
//    [self.peripherals removeObject:aPeripheral];

    if (self.isGettingBattery) {
        [[self class] cancelPreviousPerformRequestsWithTarget:self selector:@selector(restartC) object:self];
        self.isReadCurrentBattery = YES;
        self.readCount = 0;
        self.timer = [NSTimer scheduledTimerWithTimeInterval:1 repeats:YES block:^(NSTimer * _Nonnull timer) {
            if (self.isReadCurrentBattery) {
                [self readBatteryLevel];
            }
            self.readCount += 1;
            if (self.readCount >= 4) {
                //电池读取超过3次没有回应，则读取下一条电池信息
                BOOL isHave = NO;
                for (NSInteger i=0; i<self.batteryLevelSource.count; i++) {
                    NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithDictionary:self.batteryLevelSource[i]];
                    if ([[dict objectForKey:@"name"] isEqualToString:aPeripheral.name]) {
                        isHave = YES;
                        [self.batteryLevelSource removeObjectAtIndex:i];
                        [self.batteryLevelSource addObject:@{@"name": aPeripheral.name, @"batteryLevel": @"-1"}];
                        break;
                    }
                }
                if (!isHave) {
                    [self.batteryLevelSource addObject:@{@"name": aPeripheral.name, @"batteryLevel": @"-1"}];
                }
                [[NSNotificationCenter defaultCenter] postNotificationName:kBTGetBatteryLevel object:self.batteryLevelSource];
                [self.manager cancelPeripheralConnection:aPeripheral];
                self.isReadCurrentBattery = NO;
                self.peripheral = nil;
                [self.timer invalidate];
                self.timer = nil;
                [self didReciveBatteryData:nil];
            }
        }];
    }
    if (self.isGettingBattery) {
        return;
    }

    if (self.connectBlock) {
        self.connectBlock(YES);
        self.connectBlock = nil;
    }
    
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [[NSNotificationCenter defaultCenter] postNotificationName:kBTConnectDeviceName object:[self.diviceNameDict objectForKey:aPeripheral.name]];
    });
    [[NSNotificationCenter defaultCenter] postNotificationName:kBTConnectionSucceed object:aPeripheral.name];
}

/*
 *Invoked whenever an existing connection with the peripheral is torn down.
 *Reset local variables
 *设备已经断开
 */
#pragma mark 设备断开走这个方法设备已经断开
- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)aPeripheral error:(NSError *)error {
    NSLog(@"蓝牙已断开连接:%@", aPeripheral.name);
//    if (self.isGettingBattery) {
//        self.isConnectTimeOut = NO;
//        BOOL isHave = NO;
//        for (NSInteger i=0; i<self.batteryLevelSource.count; i++) {
//            NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithDictionary:self.batteryLevelSource[i]];
//            if ([[dict objectForKey:@"name"] isEqualToString:aPeripheral.name]) {
//                isHave = YES;
//                break;
//            }
//        }
//        if (!isHave) {
//            [self.batteryLevelSource addObject:@{@"name": aPeripheral.name, @"batteryLevel": @"-1"}];
//            [[NSNotificationCenter defaultCenter] postNotificationName:kBTGetBatteryLevel object:self.batteryLevelSource];
//            [[NSNotificationCenter defaultCenter] postNotificationName:kBTGetBatteryLevel object:self.batteryLevelSource];
//            [self.manager cancelPeripheralConnection:self.peripheral];
//            self.isReadCurrentBattery = NO;
//            self.peripheral = nil;
//            [self.timer invalidate];
//            self.timer = nil;
//            [self didReciveBatteryData:nil];
//            return;
//        }
//    }

    if (self.disconnectBlock) {
        self.disconnectBlock();
        self.disconnectBlock = nil;
    }
    if(self.peripheral && !self.isInitiativeDis && !self.isGettingBattery) {
//        self.peripheral.delegate = nil;
//        self.peripheral = nil;
        //由于硬件有问题，所以会出现自动断开连接的现象，所以这里默认重连这个设备
//        if (![BlutoothBatteryManager sharedBTManager].isGetBatterying) {
//            [self connectPeripheral:self.peripheral];
//        }
        [self connectPeripheral:self.peripheral];
    }
    if (self.connectBlock) {
        self.connectBlock(NO);
        self.connectBlock = nil;
    }
    self.isConnected = NO;
    self.isAutoDisconnect = YES; // 是否自动连接
 
    if (self.isGettingBattery) {
        return;
    }
    
    NSLog(@"是自动断开的");
    [[NSNotificationCenter defaultCenter] postNotificationName:kBTDisconnect object:aPeripheral.identifier.UUIDString];
}

/*
 *Invoked whenever the central manager fails to create a connection with the peripheral.
 *连接设备失败
 */
#pragma mark 连接设备失败
- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)aPeripheral error:(NSError *)error {
    if (self.isGettingBattery) {
        [[self class] cancelPreviousPerformRequestsWithTarget:self
                                                     selector:@selector(restartC)
                                                       object:self];
        BOOL isHave = NO;
        for (NSInteger i=0; i<self.batteryLevelSource.count; i++) {
            NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithDictionary:self.batteryLevelSource[i]];
            if ([[dict objectForKey:@"name"] isEqualToString:aPeripheral.name]) {
                isHave = YES;
                [self.batteryLevelSource removeObjectAtIndex:i];
                [self.batteryLevelSource addObject:@{@"name": aPeripheral.name, @"batteryLevel": @"-1"}];
                break;
            }
        }
        if (!isHave) {
            [self.batteryLevelSource addObject:@{@"name": aPeripheral.name, @"batteryLevel": @"-1"}];
            [[NSNotificationCenter defaultCenter] postNotificationName:kBTGetBatteryLevel object:self.batteryLevelSource];
            [self didReciveBatteryData:nil];
            return;
        }
    }

    NSLog(@"连接失败: %@ with error = %@", aPeripheral, [error localizedDescription]);
    if(self.peripheral) {
        self.peripheral.delegate = nil;
        self.peripheral = nil;
    }
    [[NSNotificationCenter defaultCenter] postNotificationName:kBTFailToConnect object:nil];
}

#pragma mark - 外设 的代理方法
/*
 *Invoked upon completion of a -[discoverServices:] request.
 *Discover available characteristics on interested services
 *发现服务
 */
#pragma mark - 第四步：发现服务
- (void) peripheral:(CBPeripheral *)aPeripheral didDiscoverServices:(NSError *)error {
    for (CBService *aService in aPeripheral.services) {
//        NSLog(@"Service found with UUID : %@", aService.UUID.UUIDString);
        self.kServiceUUID = [NSString stringWithFormat:@"%@", aService.UUID];
        //如果是的话就进入下一步 发现服务特征值
        if ([self.kServiceUUID isEqualToString:serviceUUID]) {
            [aPeripheral discoverCharacteristics:nil forService:aService];
        }
    }
}

/*
 *Invoked upon completion of a -[discoverCharacteristics:forService:] request.
 *Perform appropriate operations on interested characteristics
 *发现服务特征值
 */
#pragma mark 第五步：发现服务特征值
- (void) peripheral:(CBPeripheral *)aPeripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error {
    for (CBCharacteristic *characteristic in service.characteristics) {
        //把这个特征值的通知打开
//        NSLog(@"%@", characteristic.UUID.UUIDString);
        //  if ([characteristic.UUID.UUIDString hasPrefix:@"FFE1"]) {
         if ([characteristic.UUID.UUIDString hasPrefix:notifyCharacter]) {
            [_peripheral setNotifyValue:YES forCharacteristic:characteristic];
            _notifyCharacteristic=characteristic;
//            NSLog(@"notify characteristic.UUID.UUIDString = %@",characteristic.UUID.UUIDString);
        }
         if ([characteristic.UUID.UUIDString isEqualToString:writeCharacter]) {
             // 记录写入数据的特征值
//            NSLog(@"write characteristic.UUID.UUIDString = %@",characteristic.UUID.UUIDString);
            self.writeCharacteristic=characteristic;
            self.writeUUID = characteristic.UUID.UUIDString;
        }
    }

    if (self.writeCharacteristic && self.notifyCharacteristic) {
        [[NSNotificationCenter defaultCenter] postNotificationName:@"characteristicFound" object:nil];
    }
}

- (void) peripheral:(CBPeripheral *)aPeripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error {
    NSData *data;
    Byte *dataBytes;
    data = characteristic.value;
    if (!data || !data.length) {
        NSLog(@"receieve null data");
        return ;
    }
//    NSLog(@"original value%@",data);
    dataBytes = (Byte*)data.bytes;
//    NSLog(@"databyte[0]:%i",dataBytes[0]);
    //此句不可删除
    if ((dataBytes[0] == 0x01) && (self.dataLength == -1) ) {
        if  (data.length == 1) {
            self.dataLength = 8;
            [self.wholeData resetBytesInRange:NSMakeRange(0, [self.wholeData length])];
            [self.wholeData setLength:0];
        }else if  (dataBytes[1] == 0x03) {
            //数据报文长度是76，但是前面还有5个字节内容，所以还需要加5
            self.dataLength=dataBytes[2]+5;
        }
    }
    [self.wholeData appendData:data];
    self.tempDataLength = self.tempDataLength + data.length;
    //NSLog(@"tempDataLength:%li dataLength:%li",tempDataLength,dataLength);
    if (self.tempDataLength >= self.dataLength) {
        if ([self isDataCRCOK:self.wholeData]) {
//            [[BlutoothBatteryManager sharedBTManager] didReciveData:self.wholeData];
            if (self.isGettingBattery) {
                //读取电量
                [self didReciveBatteryData:self.wholeData];
            }else {
                [[NSNotificationCenter defaultCenter] postNotificationName:kBTDidReciveData object:self.wholeData];
            }
        }
        self.tempDataLength = 0;
        self.dataLength=-1;
        [self.wholeData resetBytesInRange:NSMakeRange(0, [self.wholeData length])];
        [self.wholeData setLength:0];
    }
 }

- (void)peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(nullable NSError *)error {
    NSLog(@"-------%@", error);
}

#pragma mark - lazy
- (CBCharacteristic *)writeCharacteristic {
    if (!_writeCharacteristic) {
        for (CBService *s in self.peripheral.services) {
            for (CBCharacteristic *c in s.characteristics) {
                if ([c.UUID.UUIDString isEqualToString:self.writeUUID]) {
                    _writeCharacteristic = c;
                    break;
                }
            }
            if (_writeCharacteristic) {
                break;
            }
        }
    }
    
    return _writeCharacteristic;
}

CBPeripheral *_lastPeripheral;
- (void)setIsGettingBattery:(BOOL)isGettingBattery {
    BOOL oldState = _isGettingBattery;
    _isGettingBattery = isGettingBattery;
    [self.batteryLevelSource removeAllObjects];
    if (isGettingBattery && self.peripherals.count) {
        _lastPeripheral = self.peripheral;
        self.peripheral = nil;
        [self didReciveBatteryData:nil];
    }
    if (!isGettingBattery && oldState) {
        [self.timer invalidate];
        self.timer = nil;
        if (self.peripheral) {
            [self disconnectPeripheral:self.peripheral];
            self.peripheral = nil;
        }
//        if (_lastPeripheral) {
//            [self connectPeripheral:_lastPeripheral];
//            _lastPeripheral = nil;
//        }
    }
}

- (void)didReciveBatteryData:(NSData *)reciveData {
    if (reciveData) {
        Byte *dataBytes = (Byte*)reciveData.bytes;
        if (dataBytes[2]==0x02) {
//            [ProgressHUD showSuccessMessage:@"接收到电池数据"];
            NSInteger batteryLevel = dataBytes[4];
            if (batteryLevel>100) {
                //去掉异常数据
                batteryLevel = 0;
            }
            for (CBPeripheral *peripheral in self.peripherals) {
                if ([peripheral.name isEqual:self.peripheral.name]) {
                    BOOL isAdd = NO;
                    for (NSInteger i=0; i<self.batteryLevelSource.count; i++) {
                        NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithDictionary:self.batteryLevelSource[i]];
                        if ([[dict objectForKey:@"name"] isEqualToString:self.peripheral.name]) {
                            dict[@"batteryLevel"] = [@(batteryLevel) description];
                            [self.batteryLevelSource replaceObjectAtIndex:i withObject:dict];
                            break;
                        }
                    }
                    if (!isAdd) {
                        [self.batteryLevelSource addObject:@{@"name": peripheral.name, @"batteryLevel": @(batteryLevel)}];
                    }
                    [[NSNotificationCenter defaultCenter] postNotificationName:kBTGetBatteryLevel object:self.batteryLevelSource];
                    [self.manager cancelPeripheralConnection:self.peripheral];
                    self.isReadCurrentBattery = NO;
                    self.peripheral = nil;
                    [self.timer invalidate];
                    self.timer = nil;
//                    [self.peripherals addObject:peripheral];
//                    [[NSNotificationCenter defaultCenter] postNotificationName:kBTSearchDevices object:self.peripherals];
                    break;
                }
            }
        }
    }
    if (self.peripheral) {
        return;
    }
    // 连接下一个蓝牙
    NSMutableArray *batteryNames = [NSMutableArray array];
    for (NSDictionary *dict in self.batteryLevelSource) {
        [batteryNames addObject:[dict objectForKey:@"name"]];
    }
//    NSInteger count = self.batteryLevelSource.count;
//    if (count<self.peripherals.count) {
//        CBPeripheral *peripheral = self.peripherals[count];
//        [self connectPeripheral:peripheral];
//    }
    BOOL isConnect = NO;
    for (CBPeripheral *peripheral in self.peripherals) {
        if (![batteryNames containsObject:peripheral.name]) {
//            [ProgressHUD showSuccessMessage:[NSString stringWithFormat:@"开始连接--%@", peripheral.name]];
            [self connectPeripheral:peripheral];
            isConnect = YES;
            break;
        }
    }
    if (!isConnect) {
        //检测是否有连接失败的数据，有就重连
        for (NSDictionary *dict in self.batteryLevelSource) {
            NSInteger batteryLevel = [[dict objectForKey:@"batteryLevel"] integerValue];
            if (batteryLevel == -1) {
                NSString *batteryName = [dict objectForKey:@"name"];
                for (CBPeripheral *peripheral in self.peripherals) {
                    if ([batteryName isEqualToString:peripheral.name]) {
            //            [ProgressHUD showSuccessMessage:[NSString stringWithFormat:@"开始连接--%@", peripheral.name]];
                        isConnect = YES;
                        [self connectPeripheral:peripheral];
                        return;
                    }
                }
            }
        }
    }
    if (!isConnect) {
        //如果连接电量为0的情况时，重新请求一次电量信息
        for (NSDictionary *dict in self.batteryLevelSource) {
            NSInteger batteryLevel = [[dict objectForKey:@"batteryLevel"] integerValue];
            if (batteryLevel == 0) {
                NSString *batteryName = [dict objectForKey:@"name"];
                for (CBPeripheral *peripheral in self.peripherals) {
                    if ([batteryName isEqualToString:peripheral.name]) {
            //            [ProgressHUD showSuccessMessage:[NSString stringWithFormat:@"开始连接--%@", peripheral.name]];
                        isConnect = YES;
                        [self connectPeripheral:peripheral];
                        return;
                    }
                }
            }
        }
    }
}

- (void)readBatteryLevel {
    //系统基础参数读取
    Byte bytes[8];
    bytes[0] = 0x01;
    bytes[1] = 0x03;
    bytes[2] = 0xD0;
    bytes[3] = 0x34;
    bytes[4] = 0x00;
    bytes[5] = 0x01;
    bytes[6] = 0xFD;
    bytes[7] = 0x04;

    [self sendCommand:bytes length:8];
}


@end
